package com.qdu.bussiness.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONObject;
import com.qdu.bussiness.constant.BussinessConstant;
import com.qdu.bussiness.domain.*;
import com.qdu.bussiness.mapper.BusCoachMapper;
import com.qdu.bussiness.mapper.BusInventoryMapper;
import com.qdu.bussiness.mapper.BusRentMapper;
import com.qdu.bussiness.service.IBusHireService;
import com.qdu.bussiness.service.IBusRentService;
import com.qdu.bussiness.service.IBusTicketPurchaseService;
import com.qdu.common.core.domain.AjaxResult;
import com.qdu.common.utils.SecurityUtils;
import com.qdu.common.utils.StringUtils;
import com.qdu.common.utils.id.IdUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.number.NumberStyleFormatter;
import org.springframework.stereotype.Service;
import com.qdu.bussiness.mapper.BusBillMapper;
import com.qdu.bussiness.service.IBusBillService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 账单信息Service业务层处理
 * 
 * @author qdu
 * @date 2022-03-09
 */
@Service
public class BusBillServiceImpl implements IBusBillService 
{
    @Autowired
    private BusBillMapper busBillMapper;

    @Autowired
    private IBusTicketPurchaseService busTicketPurchaseService;

    @Autowired
    private IBusHireService busHireService;

    @Autowired
    private IBusRentService busRentService;

    @Autowired
    private BusRentMapper busRentMapper;

    @Autowired
    private BusInventoryMapper busInventoryMapper;

    @Autowired
    private BusCoachMapper busCoachMapper;

    /**
     * 查询账单信息
     * 
     * @param billId 账单信息主键
     * @return 账单信息
     */
    @Override
    public BusBill selectBusBillByBillId(Long billId)
    {
        return busBillMapper.selectBusBillByBillId(billId);
    }

    /**
     * 查询账单信息列表
     * 
     * @param busBill 账单信息
     * @return 账单信息
     */
    @Override
    public List<BusBill> selectBusBillList(BusBill busBill)
    {
        if(!SecurityUtils.getUsername().equals("admin")) {
            busBill.setBillUserName(SecurityUtils.getUsername());
        }
        return busBillMapper.selectBusBillList(busBill);
    }

    /**
     * 新增账单信息
     * 
     * @param busBill 账单信息
     * @return 结果
     */
    @Override
    public int insertBusBill(BusBill busBill)
    {
        if(busBill.getBillId() == null) busBill.setBillId(IdUtil.getId());
        busBill.setBillCreateTime(new Date());
        busBill.setBillUserName(SecurityUtils.getUsername());
        return busBillMapper.insertBusBill(busBill);
    }

    /**
     * 修改账单信息
     * 
     * @param busBill 账单信息
     * @return 结果
     */
    @Override
    public int updateBusBill(BusBill busBill)
    {
        return busBillMapper.updateBusBill(busBill);
    }

    /**
     * 批量删除账单信息
     * 
     * @param billIds 需要删除的账单信息主键
     * @return 结果
     */
    @Override
    public int deleteBusBillByBillIds(Long[] billIds)
    {
        return busBillMapper.deleteBusBillByBillIds(billIds);
    }

    /**
     * 删除账单信息信息
     * 
     * @param billId 账单信息主键
     * @return 结果
     */
    @Override
    public int deleteBusBillByBillId(Long billId)
    {
        return busBillMapper.deleteBusBillByBillId(billId);
    }

    /**
     * 查询账单详情
     * @param billId
     * @return
     */
    @Override
    public AjaxResult getBillDetails(Long billId) {
        /** 查询门票消费记录 */
        BusTicketPurchase queryDto = new BusTicketPurchase();
        queryDto.setBillId(billId);
        List<BusTicketPurchase> busTicketPurchases = busTicketPurchaseService.selectBusTicketPurchaseList(queryDto);
        // 组装数据
        List<BillDetailVO> noBillDetailVOList = new ArrayList<>();
        List<BillDetailVO> paidDetailVOList = new ArrayList<>();
        for (BusTicketPurchase busTicketPurchase : busTicketPurchases) {
            BillDetailVO billDetailVO = new BillDetailVO();
            billDetailVO.setType("门票");
            billDetailVO.setContent(busTicketPurchase.getTicketName());
            billDetailVO.setAmount(Long.parseLong(busTicketPurchase.getPurchaseMoney()));
            billDetailVO.setQuantity(1L);
            billDetailVO.setTime(busTicketPurchase.getPurchaseTime());
            billDetailVO.setIsPaid(busTicketPurchase.getIsPaid());
            if(busTicketPurchase.getIsPaid() == 1L){
                // 已支付的
                paidDetailVOList.add(billDetailVO);
            }else{
                noBillDetailVOList.add(billDetailVO);
            }
        }

        /** 查询雪具租赁消费记录 */
        BusRent rentQueryDto = new BusRent();
        rentQueryDto.setBillId(billId);
        List<BusRent> busRentList = busRentService.selectBusRentList(rentQueryDto);
        for (BusRent busRent : busRentList) {
            BillDetailVO billDetailVO = new BillDetailVO();
            billDetailVO.setAmount((long)Double.parseDouble(busRent.getRentMoney()));
            billDetailVO.setQuantity(busRent.getRentQuantity());
            billDetailVO.setTime(busRent.getRentStartTime());
            billDetailVO.setIsPaid(busRent.getIsPaid());
            if(busRent.getRentType().equals(BussinessConstant.RENT_TYPE_DEPOSIT)){
                billDetailVO.setType("押金");
                billDetailVO.setContent("租赁雪具押金");
                paidDetailVOList.add(billDetailVO);
            }else{
                billDetailVO.setType("佣金");
                billDetailVO.setContent("租赁雪具");
                if(busRent.getIsPaid().equals(0L)){
                    noBillDetailVOList.add(billDetailVO);
                }else {
                    paidDetailVOList.add(billDetailVO);
                }
            }
        }

        /** 查询教练雇佣消费记录 */
        BusHire queryHire = new BusHire();
        queryHire.setBillId(billId);
        List<BusHire> busHires = busHireService.selectBusHireList(queryHire);
        for (BusHire busHire : busHires) {
            BillDetailVO billDetailVO = new BillDetailVO();
            billDetailVO.setType("佣金");
            billDetailVO.setContent("雇佣教练");
            billDetailVO.setAmount((long)Double.parseDouble(busHire.getHireMoney()));
            billDetailVO.setQuantity(1L);
            billDetailVO.setTime(busHire.getHireStartTime());
            billDetailVO.setIsPaid((long)busHire.getIsPaid());
            if(busHire.getIsPaid().equals(0)){
                // 未支付
                noBillDetailVOList.add(billDetailVO);
            }else{
                paidDetailVOList.add(billDetailVO);
            }
        }

        JSONObject resultObject = new JSONObject();
        resultObject.put("notPaidDetails", noBillDetailVOList);
        resultObject.put("paidDetails", paidDetailVOList);
        return AjaxResult.success(resultObject);
    }

    /**
     * 查询某人当前的账单情况
     * @param userName
     * @return
     */
    @Override
    public BusBill getUserTodayBillInfo(String userName) {
        Date date = new Date();
        SimpleDateFormat start_simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        String startTime = start_simpleDateFormat.format(date);
        SimpleDateFormat end_simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        String endTime = end_simpleDateFormat.format(date);
        return busBillMapper.getUserTodayBillInfo(userName, startTime, endTime);
    }

    /**
     * 结算账单
     * @param billId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult settleBill(Long billId) {
        // 判断当前账单状态是否为 已结算
        BusBill busBill = busBillMapper.selectBusBillByBillId(billId);
        if(!busBill.getBillIsPaid().equals(0L)){
            return AjaxResult.error("当前账单已结算，无需重复结算！请刷新页面！");
        }
        /** 查询门票消费记录 */
        BusTicketPurchase queryDto = new BusTicketPurchase();
        queryDto.setBillId(billId);
        queryDto.setIsPaid(0l);
        List<BusTicketPurchase> busTicketPurchases = busTicketPurchaseService.selectBusTicketPurchaseList(queryDto);

        /** 查询雪具租赁消费记录 */
        BusRent rentQueryDto = new BusRent();
        rentQueryDto.setBillId(billId);
        rentQueryDto.setIsPaid(0L);
        List<BusRent> busRentList = busRentService.selectBusRentList(rentQueryDto);

        /** 查询教练雇佣消费记录 */
        BusHire queryHire = new BusHire();
        queryHire.setBillId(billId);
        queryHire.setIsPaid(0);
        List<BusHire> busHires = busHireService.selectBusHireList(queryHire);

        // 1.汇总总金额
        BigDecimal busTicketPurchasesSum = busTicketPurchases.stream().map(BusTicketPurchase::getPurchaseMoney).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal busRentSum = busRentList.stream().map(BusRent::getRentMoney).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal busHiresSum = busHires.stream().map(BusHire::getHireMoney).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal totalMoney = busTicketPurchasesSum.add(busRentSum).add(busHiresSum);

        // 2.查询账户总金额
        String currentBalance = busRentMapper.selectUserBalanceByUserName(SecurityUtils.getUsername());
        BigDecimal currentBalanceDecimal = BigDecimal.valueOf(Double.parseDouble(currentBalance));
        if(currentBalanceDecimal.compareTo(totalMoney) < 0){
            return AjaxResult.error("当前账号余额不足，请充值后再结算！当前剩余：" + currentBalance + " 元，账单总额：" + totalMoney + " 元。");
        }

        // 3.扣除总费用
        BigDecimal balance = currentBalanceDecimal.subtract(totalMoney);
        int balRes = busRentMapper.updateUserBalanceByUserName(SecurityUtils.getUsername(), balance.toString());
        if(balRes < 1){
            return AjaxResult.error("扣费失败！");
        }

        // 4.修改账单状态 / 门票状态
        for (BusTicketPurchase busTicketPurchase : busTicketPurchases) {
            BusTicketPurchase updateTicketPurchase = new BusTicketPurchase();
            updateTicketPurchase.setPurchaseId(busTicketPurchase.getPurchaseId());
            updateTicketPurchase.setIsPaid(1L);
            updateTicketPurchase.setPurchaseStatus(BussinessConstant.PURCHASE_TICKET_STATUS_OVERTIME);
            int updPurchaseRes = busTicketPurchaseService.updateBusTicketPurchase(updateTicketPurchase);
            if(updPurchaseRes < 1){
                throw new RuntimeException("结算门票费用失败！请重试！");
            }
        }

        for (BusRent busRent : busRentList) {
            BusRent updateRent = new BusRent();
            updateRent.setRentId(busRent.getRentId());
            updateRent.setIsPaid(1L);
            int updRentRes = busRentService.updateBusRent(updateRent);
            if(updRentRes < 1){
                throw new RuntimeException("结算雪具租赁费用失败！请重试！");
            }
            // 释放对应雪具
            BusInventory udpInventory = new BusInventory();
            udpInventory.setInventoryId(busRent.getInventoryId());
            udpInventory.setInventoryStatus(BussinessConstant.INVENTORY_STATUS_NORMAL);
            int inventoryRes = busInventoryMapper.updateBusInventory(udpInventory);
            if(inventoryRes < 1){
                throw new RuntimeException("释放对应雪具失败！");
            }
        }

        for (BusHire busHire : busHires) {
            BusHire updateHire = new BusHire();
            updateHire.setHireId(busHire.getHireId());
            updateHire.setIsPaid(1);
            int updHireRes = busHireService.updateBusHire(updateHire);
            if(updHireRes < 1){
                throw new RuntimeException("结算教练雇佣费用失败！请重试！");
            }
            // 释放教练
            BusCoach updCoach = new BusCoach();
            updCoach.setCoachId(busHire.getCoachId());
            updCoach.setCoachStatus(BussinessConstant.COACH_STATUS_FREE);
            int coachRes = busCoachMapper.updateBusCoach(updCoach);
            if(coachRes < 1){
                throw new RuntimeException("释放对应教练失败！");
            }
        }

        // 5.修改总账单状态
        BusBill updBillDto = new BusBill();
        updBillDto.setBillId(billId);
        updBillDto.setBillIsPaid(1L);
        int billRes = busBillMapper.updateBusBill(updBillDto);
        if(billRes < 1){
            throw new RuntimeException("账单状态更新失败！请重试！");
        }

        // 归还押金
        BusRent rentQueryDto2 = new BusRent();
        rentQueryDto2.setBillId(billId);
        rentQueryDto2.setIsPaid(1L);
        List<BusRent> depositRent = busRentService.selectBusRentList(rentQueryDto2);
        Double depositTotal = new Double(0.00);
        for (BusRent busRent : depositRent) {
            if(StringUtils.isNotEmpty(busRent.getRentMoney())){
                depositTotal += Double.parseDouble(busRent.getRentMoney());
            }
        }
        if(!depositTotal.equals(0.00)){
            // 修改账号押金数
            int balanceRes = busRentMapper.addBalanceByUserName(SecurityUtils.getUsername(), depositTotal);
            if(balanceRes < 1){
                throw new RuntimeException("押金退还失败！");
            }
        }

        return AjaxResult.success();
    }
}
